package cn.com.surker.workcon.service.zhcl;

import cn.com.surker.base.system.entity.SysLine;
import cn.com.surker.lab.dao.LabLevelOptimizeMaterialDao;
import cn.com.surker.lab.vo.OptimizeMaterialVo;
import cn.com.surker.production.entity.vo.ProductionIndentVo;
import cn.com.surker.util.RandomUtils;
import cn.com.surker.util.StringUtils;
import cn.com.surker.workcon.common.GKJDBCService;
import cn.com.surker.workcon.common.RecipeTranEntity;
import cn.com.surker.workcon.service.RecipeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 珠海长路工控上传配比接口 Mapper 接口
 * </p>
 *
 * @author admin
 * @since 2024-09-26
 */
@Slf4j
public class RecipeServiceImpl extends GKJDBCService implements RecipeService {

	@Resource
	private LabLevelOptimizeMaterialDao labLevelOptimizeMaterialDao;

	/**
	 * 上传配合比数据
	 *
	 * @param line    工控机生产线
	 * @param indent  任务单信息
	 * @param code    配合比编号(砂浆在配合比前加入R)
	 * @param betLev  强度等级名
	 * @param filter  抗渗等级
	 * @param freeze  抗冻等级
	 * @param season  施工季节
	 * @param mixLast 搅拌时间
	 * @param exper   试验员
	 * @param assoss  审核员
	 * @param list    配合比数据
	 * @return
	 */
	@Override
	public Long uploadExpend(SysLine line, ProductionIndentVo indent, String code, String betLev, String filter, String freeze, String season,
							 Integer mixLast, String scale, String exper, String assoss, List<RecipeTranEntity> list, Date nowDate) {
		if (line == null || indent == null || list == null || list.isEmpty()) {
			return -1l;
		}
		Long lineId = line.getId();
		//	获取连接
		JdbcTemplate lineJdbcTemp = getLineJdbcTemp(line);
		//	任务单编号
		String indentCode = indent.getCode();
		//	根据任务单编号,查询是否存在上传数据
		String productTaskTable = ZhclUtil.getCtrlTableName(line, "ProductTask");
		String queryOldTask = "select id from " + productTaskTable + " where Code = '" + indentCode + "'";
		//	查询数据
		List<Map<String, Object>> oldTasks = lineJdbcTemp.queryForList(queryOldTask);
		if (oldTasks == null || oldTasks.isEmpty() || oldTasks.get(0) == null) {
			//	没有上传数据
			log.info("任务单{}没有查询到工控数据", indentCode);
			return -1l;
		}
		//	强度等级
		Long strengthId = indent.getStrengthId();
		//	塌落度
		String slumps = indent.getSlumps();
		//	浇筑方式
		String castModelName = indent.getCastModelName();
		//	上传砼配合比数据
		//	配合比编号
		String tongCode = code;
		//	强度等级名称
		String tongName = betLev;
		//	先查询配合比是否存在
		String recipeMainTable = ZhclUtil.getCtrlTableName(line, "RecipeMain");
		String queryMainIdSql = "select id from " + recipeMainTable + " where code = ?";
		Object[] queryMainParam = {code};
		List<Map<String, Object>> oldMaps = lineJdbcTemp.queryForList(queryMainIdSql, queryMainParam);
		Long recipeMainId = null;
		if (oldMaps != null && oldMaps.size() > 0) {
			recipeMainId = Long.valueOf(oldMaps.get(0).get("id").toString());
		}
		//	更新任务单的数据
		String tc1 = null, tc2 = null, standTc1 = null, standTc2 = null;

		String updateTaskSql = "update " + productTaskTable + " set TC1 = ?,TC2 = ? where Code = ?";
		//	更新任务单的配合比
		Long controlLineId = line.getControlLineId();
		if (controlLineId == 1) {
			tc1 = code;
			standTc1 = "R" + code;
		} else {
			tc2 = code;
			standTc2 = "R" + code;
		}
		//	砂浆的任务单号
		String standIndentCode = "R" + indentCode;
		//	设置任务单的配合比编号
		Object[] taskParams = {tc1, tc2, indentCode};
		Object[] standParams = {standTc1, standTc2, standIndentCode};
		//	开启事务
		beginTransaction(lineId);
		lineJdbcTemp.update(updateTaskSql, taskParams);
		lineJdbcTemp.update(updateTaskSql, standParams);
		//	上传配合比
		if (recipeMainId == null) {
			//	存在数据,新增配合比
			recipeMainId = addPhb(line, lineJdbcTemp, tongCode, tongName, slumps, castModelName, mixLast, list, 0, strengthId);
			//	上传砂浆配合比数据
			String standCode = "R" + code;
			String standName = "润管砂浆";
			addPhb(line, lineJdbcTemp, standCode, standName, slumps, castModelName, mixLast, list, 1, strengthId);
		} else {
			//	更新数据
			updatePhb(line, lineJdbcTemp, tongCode, list, 0, strengthId);
			//	砂浆数据
			String standCode = "R" + code;
			updatePhb(line, lineJdbcTemp, standCode, list, 1, strengthId);
		}
		return recipeMainId;
	}


	/**
	 * 新增配合比
	 *
	 * @param lineJdbcTemp
	 * @param code
	 * @param name
	 * @param slumps
	 * @param castModelName
	 * @param mixLast
	 * @param list
	 * @param type
	 * @return
	 */
	private Long addPhb(SysLine line, JdbcTemplate lineJdbcTemp, String code, String name, String slumps, String castModelName, Integer mixLast, List<RecipeTranEntity> list, int type, Long strengthId) {
		//	插入sql
		String recipeMainTable = ZhclUtil.getCtrlTableName(line, "RecipeMain");
		String insertMainSql = "insert into " + recipeMainTable + " (ID,Code,Name,IfValid,Grade,Degree,SendType,MixTime,I2) values (?,?,?,?,?,?,?,?,?)";
		//	查询最大的id值
		String maxMainIdSql = "select MAX(id) maxId from " + recipeMainTable;
		Long recipeMainId = 0l;
		List<Map<String, Object>> recipeMainIdDatas = lineJdbcTemp.queryForList(maxMainIdSql);
		if (recipeMainIdDatas != null && recipeMainIdDatas.size() > 0) {
			Map<String, Object> map = recipeMainIdDatas.get(0);
			Object maxId = map.get("maxId");
			recipeMainId = Long.valueOf(maxId.toString());
		}
		recipeMainId = recipeMainId + 1;
		// 拼接参数
		Object[] insertMainParam = {recipeMainId, code, name, 1, name, slumps, castModelName, mixLast, 1};
		//	插入主表数据
		lineJdbcTemp.update(insertMainSql, insertMainParam);
		//	================插入子表数据================
		//	查询标准配合比
		List<OptimizeMaterialVo> optimizeMaterialList = getOptimizeMaterial(line, strengthId);
		//	插入子表sql
		String recipeDetailTable = ZhclUtil.getCtrlTableName(line, "RecipeDetail");
		String insertDetailSql = "insert into " + recipeDetailTable + " (ID,Recipe_Code,Material_Code,Standard_Dosage,ErrorMinus,ErrorPlus,Remark) values (?,?,?,?,?,?,?)";
		List<Object[]> params = new ArrayList<>();
		//	查询材料表的数据
		String storeHouseTable = ZhclUtil.getCtrlTableName(line, "StoreHouse");
		String selectStoreSql = "select Name,LoadMaterial from " + storeHouseTable;
		List<Map<String, Object>> storeList = lineJdbcTemp.queryForList(selectStoreSql);
		for (Map<String, Object> store : storeList) {
			//	erp的仓位
			String storeName = String.valueOf(store.get("Name"));
			//	真实值
			Double realValue = 0d;
			//	b库值
			Double BValue = 0d;
			//	取出对应的消耗
			for (RecipeTranEntity recipeTranEntity : list) {
				String controlStorage = recipeTranEntity.getControlStorage();
				//	比较仓位是否对应的值
				if (storeName.equals(controlStorage)) {
					//	是对应的值
					if (type == 1) {
						//	表示砂浆
						realValue = recipeTranEntity.getStandDosage();
						// BValue = realValue;
					} else {
						//	表示砼
						realValue = recipeTranEntity.getConcreteDosage();
						// BValue = realValue;
					}
					break;
				}
			}
			//	取出仓位对应的b库消耗
			for (OptimizeMaterialVo materialVo : optimizeMaterialList) {
				String controlStorage = materialVo.getControlStorage();
				if (storeName.equals(controlStorage)) {
					//	是对应的值
					Double used = materialVo.getUsed();
					BValue = used;
				}
			}
			Long loadMaterial = Long.valueOf(String.valueOf(store.get("LoadMaterial")));
			Long id = loadMaterial + 1;
			//	拼接参数
			Object[] param = {id, code, loadMaterial, BValue, 0, 0, realValue};
			params.add(param);
		}
		//	插入数据
		lineJdbcTemp.batchUpdate(insertDetailSql, params);
		return recipeMainId;
	}

	/**
	 * 更新子表数据
	 *
	 * @param lineJdbcTemp
	 * @param code
	 * @param list
	 * @param type
	 */
	private void updatePhb(SysLine line, JdbcTemplate lineJdbcTemp, String code, List<RecipeTranEntity> list, int type, long strengthId) {
		//	先删除子表数据
		String recipeDetailTable = ZhclUtil.getCtrlTableName(line, "RecipeDetail");
		String delDetailSql = "delete from " + recipeDetailTable + " where Recipe_Code = ?";
		Object[] delDetailParam = {code};
		lineJdbcTemp.update(delDetailSql, delDetailParam);
		//	================插入子表数据================
		//	查询标准配合比
		List<OptimizeMaterialVo> optimizeMaterialList = getOptimizeMaterial(line, strengthId);
		//	插入子表sql
		String insertDetailSql = "insert into " + recipeDetailTable + " (ID,Recipe_Code,Material_Code,Standard_Dosage,ErrorMinus,ErrorPlus,Remark) values (?,?,?,?,?,?,?)";
		List<Object[]> params = new ArrayList<>();
		//	查询材料表的数据
		String storeHouseTable = ZhclUtil.getCtrlTableName(line, "StoreHouse");
		String selectStoreSql = "select Name,LoadMaterial from " + storeHouseTable;
		List<Map<String, Object>> storeList = lineJdbcTemp.queryForList(selectStoreSql);
		for (Map<String, Object> store : storeList) {
			//	erp的仓位
			String storeName = String.valueOf(store.get("Name"));
			//	真实值
			Double realValue = 0d;
			//	b库值
			Double BValue = 0d;
			//	取出仓位对应的消耗
			for (RecipeTranEntity recipeTranEntity : list) {
				String controlStorage = recipeTranEntity.getControlStorage();
				if (storeName.equals(controlStorage)) {
					//	是对应的值
					if (type == 1) {
						//	表示砂浆
						realValue = recipeTranEntity.getStandDosage();
						// BValue = realValue;
					} else {
						//	表示砼
						realValue = recipeTranEntity.getConcreteDosage();
						// BValue = realValue;
					}
					break;
				}
			}
			//	取出仓位对应的b库消耗
			for (OptimizeMaterialVo materialVo : optimizeMaterialList) {
				String controlStorage = materialVo.getControlStorage();
				if (storeName.equals(controlStorage)) {
					//	是对应的值
					Double used = materialVo.getUsed();
					BValue = used;
				}
			}
			Long loadMaterial = Long.valueOf(String.valueOf(store.get("LoadMaterial")));
			Long id = loadMaterial + 1;
			//	拼接参数
			Object[] param = {id, code, loadMaterial, BValue, 0, 0, realValue};
			params.add(param);
		}
		//	插入数据
		lineJdbcTemp.batchUpdate(insertDetailSql, params);
	}

	private List<OptimizeMaterialVo> getOptimizeMaterial(SysLine line, Long strengthId) {
		Long lineId = line.getId();
		List<OptimizeMaterialVo> strengthIdOrControl = labLevelOptimizeMaterialDao.findStrengthIdOrControl(lineId, strengthId);
		if (strengthIdOrControl == null || strengthIdOrControl.isEmpty()) {
			strengthIdOrControl = labLevelOptimizeMaterialDao.findStrengthIdOrControlV1(lineId, strengthId);
		}
		if (strengthIdOrControl == null) {
			strengthIdOrControl = new ArrayList<>();
		}
		return strengthIdOrControl;
	}

}
